<?php

namespace App\Process;

use App\Model\RecordsModel;
use App\Model\TestModel;
use App\Model\TmplmsgsModel;
use App\Model\UsersModel;
use App\Queue\Queue;
use App\Task\ArticleTask;
use App\Utility\Cache;
use App\Utility\MiniProgram;
use Carbon\Carbon;
use EasySwoole\EasySwoole\Logger;
use EasySwoole\Component\Process\AbstractProcess;
use EasySwoole\EasySwoole\Swoole\Task\TaskManager;

class MessagePush extends AbstractProcess
{
    private $isRun = false;
    public function run($arg){
        //定时500ms检测有没有任务，有的话就while死循环执行
        $this->addTick(200,function (){
            if(!$this->isRun){
                $this->isRun = true;
                for ($i = 1; $i <= 2; $i++) {
                    go(function (){
                        while (true) {
                            try {
                                $cache = new Cache();
                                //从openid_push集合中随机去一个openid进行推送消息
                                $openid_string = $cache->sPop('openid_push');
                                if ($openid_string) {
                                    $data = explode('*',$openid_string);
                                    if(is_array($data)){
                                        $applet = $data[0];
                                        $openid = $data[1];
//                                        Logger::getInstance()->log($applet.'-'.$openid,'TemplateMessage');
                                        //读取模板消息内容
                                        $templateInfo = $cache->get('template_'.$applet);
                                        //根据openid取找到相应的openid的formid的集合，先删除该集合已过期的所有的formid,
                                        $cache->zRemRangeByScore($openid,0,time()+10);
                                        //如果openid的formid的集合没有值，终止while
                                        if($cache->zCard($openid) == 0){
                                            $cache->srem($applet,$openid_string);
                                            unset($cache);
                                            break;
                                        }

                                        //判断
                                        $push_num = $cache->sPop('push_number');
                                        if(!$push_num){
                                            unset($push_num);
                                            unset($cache);
                                            break;
                                        }

                                        //然后取一个formid的值
                                        $formid_array = $cache->zRange($openid,0,0);
                                        if(count($formid_array)){
                                            $formid = $formid_array[0];
                                            //组装推送的模板消息内容
                                            $emphasis_keyword = '';
                                            if($templateInfo['emphasis']) {
                                                //存在，拼接返回字符串
                                                $emphasis_keyword = $templateInfo['emphasis'] . ".DATA"; //将keyword放大
                                            }
                                            //微信模板消息推送
                                            $wechat = new MiniProgram($applet);
                                            $sendData = [
                                                'touser' => $openid,
                                                'template_id' => $templateInfo['template_id'],
                                                'page' => trim($templateInfo['page']),
                                                'form_id' => $formid,
                                                'data' => $templateInfo['keywords'][0],
                                                'emphasis_keyword' => $emphasis_keyword,
                                            ];
                                            $result = $wechat->sendTemplateMessage($sendData);
                                            $recordModel = new RecordsModel();

//                                            Logger::getInstance()->log($applet.'-'.json_encode($result),'TemplateMessage');
                                            if ($result['errcode'] == 0) {
                                                //从集合中移除该formid
                                                $cache->zrem($openid,$formid);
                                                //如果删除集合中过期的formid值后该集合为空，则删除对应的小程序的openid集合中的openid元素
                                                if($cache->zCard($openid) == 0) $cache->srem($applet,$openid_string);
                                                $recordModel->inc($templateInfo['record_id'], 'success_number');
//                                                $cache->inc($recordKey);
//                                                if($cache->ttl($recordKey) < 0){
//                                                    $cache->expire($recordKey,60*60);
//                                                }
                                            } else {
                                                if(($result['errcode'] == 41028) || ($result['errcode'] == 41029)){
                                                    $cache->zrem($openid,$formid);
                                                    //如果删除集合中过期的formid值后该集合为空，则删除对应的小程序的openid集合中的openid元素
                                                    if($cache->zCard($openid) == 0) $cache->srem($applet,$openid_string);
                                                }
                                                $recordModel->inc($templateInfo['record_id'], 'faild_number');
                                            }
                                            unset($recordModel);
                                        }
                                    }
                                }
                                unset($cache);
                            } catch (\Throwable $throwable) {
                                throw new \Exception($throwable->getMessage());
                            }
                        }
                        $this->isRun = false;
                    });
                }
            }
        });
    }

    public function onShutDown()
    {
        // TODO: Implement onShutDown() method.
    }

    public function onReceive(string $str, ...$args)
    {
        // TODO: Implement onReceive() method.
    }
}
